"""

Problem-specific gui operators

"""

# Import schema modules
from tasks.libs import visualizer

# Import DEXEN modules
from dexen.user.libs.algorithms import ea
from dexen.user.libs import gui_api

""" GLOBALS """

# For each graph a separate GraphAPI object has to be created.

# The population graph
pop_graph = gui_api.GraphAPIFactory(
    type=gui_api.POP_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Population Size",
    title="Population Graph"
)

# The first objective graph
obj_graph1 = gui_api.GraphAPIFactory(
    type=gui_api.OBJ_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Width",
    title="Width Objective Graph"
    
)

# The second objective graph
opj_graph2 = gui_api.GraphAPIFactory(
    type=gui_api.OBJ_GRAPH, 
    x_axis_name="No of Births", 
    y_axis_name="Height",
    title="Height Objective Graph"
)

#The pareto graph
pareto_graph = gui_api.GraphAPIFactory(
    type=gui_api.PARETO_GRAPH, 
    x_axis_name="Width", 
    y_axis_name="Height",
    title="Pareto Graph"
)

def updatePopulationGraph(time):
    
    # For the population graph, only the number of live individuals needs to 
    # be retrieved.
    num_live_individuals = pop_api.countLiveIndividuals(at_time = timer)
    pop_graph.addData(x = timer, y = num_live_individuals)         
    
def updateObjectiveGraph1(individuals, time):
    """
    Operator that updates the objective graph for the first objective.
    """
    
    # UPDATE THE NAME OF THE OBJECTIVE
    objective_name = "xxx"
    
    min_value = min([ind[objective_name] for ind in inds])
    max_value = max([ind[objective_name] for ind in inds])
    
    obj_graph1.addData(time, min_value)
    obj_graph1.addData(time, max_value)

def updateObjectiveGraph2(individuals, time):
    """
    Operator that updates the objective graph for the second objective.
    """
    
    # UPDATE THE NAME OF THE OBJECTIVE
    objective_name = "xxx"
    
    min_value = min([ind[objective_name] for ind in inds])
    max_value = max([ind[objective_name] for ind in inds])
    
    obj_graph2.addData(time, min_value)
    obj_graph2.addData(time, max_value)
    
def updateParetoGraph(individuals):
    """
    Operator that updates the pareto graph.
    """
    
    # UPDATE THE NAMES OF THE OBJECTIVE
    objective1_name = "xxx"
    objective2_name = "xxx"
    
    env_selector = ea.EnvironmentalSelection() 
    env_selector.setObjectives(
         (objective1_name, dc.MINIMIZE),
         (objective2_name, dc.MINIMIZE)
    )
    pareto_front = env_selector.filterDominatedOnes(inds)

    for individual in pareto_front:
        pareto_graph.addData(individual[objective1_name], individual[objective2_name], individual["id"])

    


